package App.Model;

import App.Model.Interface.MessageType;
import App.Model.message.Message;
import App.OO.service.thread.CtoSThread;
import App.OO.service.thread.Manage.ManageCtoSThread;
import com.alibaba.fastjson.JSON;

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

//用于将服务器或者用户的聊天记录与用户信息在外部存储中提取或者写入
public class ArisuDB implements Serializable {
    @Serial
    private static final long serialVersionUID = 1L;
    public static boolean isChange;//用于提醒服务器数据发生了改变
    private static HashMap<String, User> userMap;//储存所有用户<userId : User>
    private static HashMap<String, List<Message>> MessageData;//储存过去的聊天记录<userId : MessageList>(用户)
    private static HashMap<String, List<Message>> newMessageData = new HashMap<>();//储存离线消息对应用户登录的时候会加载<userId : MessageList>

    static {//读取userMap
        isChange = false;
        userMap = getUserMapAtFile();
        if (userMap == null) {
            userMap = new HashMap<>();
        }
        newMessageData = getNewMessageDataAtFile();
        if(newMessageData == null) {
            newMessageData = new HashMap<>();
        }

    }

    public static void addUserMap(String userId, User user) {
        userMap.put(userId, user);
    }

    public static void addAllUserMap(HashMap<String, User> userMap) {//使用深拷贝,可能有用..
        for (Map.Entry<String, User> entry : userMap.entrySet()) {
            System.out.println("Key: " + entry.getKey() + ", Value: " + entry.getValue());
            userMap.put(entry.getKey(), (User) entry.getValue());
        }
    }

    public static boolean saveUserMapToFile() {//将userMap写入文件
        try (
                FileOutputStream fos = new FileOutputStream("src\\main\\resources\\data\\userMap.ser");
                ObjectOutputStream oos = new ObjectOutputStream(fos)) {
            oos.writeObject(userMap);

        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    public static HashMap<String, User> getUserMapAtFile() {//从外部文件中获取数据
        HashMap<String, User> loadedMap = null;
        //Path filePath = Paths.get("D:\\编程\\java文件\\OO\\App\\data\\userMap.ser");
        Path filePath = Paths.get("src\\main\\resources\\data\\userMap.ser");

        try {
            // 检查文件是否存在并且其大小大于0
            if (Files.exists(filePath) && Files.size(filePath) > 0) {
                try (ObjectInputStream in = new ObjectInputStream(new FileInputStream(filePath.toFile()))) {
                    Object obj = in.readObject(); // 你的Object对象
                    loadedMap = (HashMap<String, User>) obj;
                    System.out.println("成功加载注册用户数据..");
                    return loadedMap;
                } catch (IOException | ClassNotFoundException e) {
                    e.printStackTrace();
                    return null;
                }
            } else {
                System.out.println("无注册用户");
                return null; // 或者你可以返回一个空的HashMap，取决于你的需求
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    //在服务器关闭时应当储存newMessageData..
    public static List<Message> getOfflineMessage(String userId) {//获取离线数据
        List<Message> returnData = newMessageData.get(userId);
        return returnData;
    }

    public static void putOfflineMessage(String UserId, Message message) {//UserId: 接收者
        List<Message> messages = newMessageData.get(UserId);
        if (messages == null) {
            messages = new ArrayList<>();
        }
        messages.add(message);
        newMessageData.put(UserId, messages);
    }

    public static StringBuilder getAllUserToString() {//获取注册用户列表  写完好友系统后应该会没用
        StringBuilder data = new StringBuilder();
        for (String s : userMap.keySet()) {
            data.append(s.toString()).append(" ");
        }
        data.append("| ");//用作分隔符
        return data;
    }

    public static boolean isExistUser(String userId) {//判断userId用户是否已经注册
        User user = userMap.get(userId);
        return user != null;
    }

    public static HashMap<String, User> getUserMap() {
        return userMap;
    }

    public static void cleanAllUserMap() {//清空存储的userMap文件
        try {
            File file = new File("src\\main\\resources\\data\\userMap.ser");
            FileOutputStream fos = new FileOutputStream(file);
            ObjectOutputStream oos = new ObjectOutputStream(fos);
            oos.writeObject(null); // 将 null 对象写入文件，清空文件内容
            oos.close();
            fos.close();
            System.out.println("清空userMap文件");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void cleanNewMessageData(String userId) {
        //ArrayList<Message> empty = new ArrayList<>();
        newMessageData.put(userId, null);
        saveNewMessageDataToFile();//这么做很浪费性能,但当一个完整的服务器端管理界面完成前,只能这么做
    }

    public static void reNameAllUser(){//重命名所有用户
        for (Map.Entry<String, User> entry : userMap.entrySet()) {
            System.out.println("用户: " + entry.getKey() + "原用户名:  " + entry.getValue().getUserName() + "改为: 用户" + entry.getKey());
            entry.getValue().setUserName("用户" + entry.getKey());
            saveUserMapToFile();
        }
        isChange = true;
    }
    public static void showAllUser(){//展示所有用户信息
        for (Map.Entry<String, User> entry : userMap.entrySet()) {
            String jsonUser = JSON.toJSONString(entry.getValue());
            System.out.println(jsonUser);
        }
        isChange = true;
    }

    public static void saveServiceTempSaveFile(Message message){//将文件传输暂时保存在服务器
        String uniqueSrc =
                "src\\main\\resources\\data\\serviceTempSaveFile\\"
                        + message.getGetter() + message.getFileuniquenum() + ".ser";

        ObjectOutputStream oos = null;
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(uniqueSrc);
            oos = new ObjectOutputStream(fos);
            oos.writeObject(message);

        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                if(oos != null){
                    oos.close();
                }
                if(fos != null){
                    fos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    public static Message readServiceTempSaveFile(Message message){//从服务器提取文件传输
        if(message.getFileuniquenum() == 0){//旧版本的文件读取
            Message returnMessage = new Message();
            System.out.println("(旧版本文件)");
            returnMessage.setMesType(MessageType.MESSAGE_FILE_MSG_EXPIRE);
            return returnMessage;
        }

        Message returnMessage = null;
        String uniqueSrc =
                "src\\main\\resources\\data\\serviceTempSaveFile\\"
                        + message.getSender() + message.getFileuniquenum() + ".ser";
        Path filePath = Paths.get(uniqueSrc);
        if(message.getMesType().equals(MessageType.MESSAGE_FILE_MSG_NOTGET)){//如果不需要文件就将文件删除
            try {
                returnMessage = new Message();
                Files.deleteIfExists(filePath);
                returnMessage.setFileuniquenum(message.getFileuniquenum());
                returnMessage.setMesType(MessageType.MESSAGE_FILE_MSG_NOTGET_SUCCEED);
                System.out.println("(删除文件)");
                Files.deleteIfExists(filePath);//被接收后就可以删除
                return returnMessage;
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }

        try {
            // 检查文件是否存在并且其大小大于0
            if (Files.exists(filePath) && Files.size(filePath) > 0) {
                try (ObjectInputStream in = new ObjectInputStream(new FileInputStream(filePath.toFile()))) {
                    Object obj = in.readObject(); // 你的Object对象
                    in.close();
                    returnMessage = (Message) obj;
                    returnMessage.setMesType(MessageType.MESSAGE_FILE_MSG_GET_SUCCEED);
                    Files.deleteIfExists(filePath);//被接收后就可以删除
                    return returnMessage;
                } catch (IOException | ClassNotFoundException e) {
                    e.printStackTrace();
                    return null;
                }
            } else {
                returnMessage = new Message();
                System.out.println("(文件不存在)");
                returnMessage.setMesType(MessageType.MESSAGE_FILE_MSG_EXPIRE);
                return returnMessage;
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public static void changeUserPwd(String userId){
        User aimUser = userMap.get(userId);
        if(aimUser != null){
            userMap.get(userId).setPassword("1230");
            isChange = true;
        }
    }

    public static boolean saveNewMessageDataToFile() {//将newMessageData写入文件
        try (
                FileOutputStream fos = new FileOutputStream("src\\main\\resources\\data\\newMessageData.ser");
                ObjectOutputStream oos = new ObjectOutputStream(fos)) {
            oos.writeObject(newMessageData);

        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    public static HashMap<String, List<Message>>  getNewMessageDataAtFile() {//从外部文件中获取数据
        HashMap<String, List<Message>>  loadedMap = null;
        //Path filePath = Paths.get("D:\\编程\\java文件\\OO\\App\\data\\userMap.ser");
        Path filePath = Paths.get("src\\main\\resources\\data\\newMessageData.ser");

        try {
            // 检查文件是否存在并且其大小大于0
            if (Files.exists(filePath) && Files.size(filePath) > 0) {
                try (ObjectInputStream in = new ObjectInputStream(new FileInputStream(filePath.toFile()))) {
                    Object obj = in.readObject(); // 你的Object对象
                    loadedMap = (HashMap<String, List<Message>> ) obj;
                    System.out.println("成功加载离线消息..");
                    return loadedMap;
                } catch (IOException | ClassNotFoundException e) {
                    e.printStackTrace();
                    return null;
                }
            } else {
                System.out.println("无离线消息");
                return null; // 或者你可以返回一个空的HashMap，取决于你的需求
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public static void saveUserHeaderToFile(Message message,String fileType,String userId){
        //这个方法会影响效率,但是在不获取用户详细数据的时候,会更方便
        //message 的 byte[]
        String url = "src\\main\\resources\\data\\userHeader\\" + userId + "." + fileType;
        try {
            FileOutputStream fileOutputStream = new FileOutputStream(url);
            fileOutputStream.write(message.getFileBytes());
            fileOutputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static byte[] getUserHeaderAtFile(User user){
        //获取这个用户的头像(userId + fileType)
        String url = "src\\main\\resources\\data\\userHeader\\" + user.getUserId() + "." + user.getHeaderUrl();

        byte[] returnByte;
        try {
            // 使用Files类的readAllBytes方法读取文件内容到byte数组中
            returnByte = Files.readAllBytes(Paths.get(url));
//            System.out.println("文件大小（字节）: " + returnByte.length);
            return returnByte;
        } catch (IOException e) {
            // 处理文件读取时可能发生的异常
            //e.printStackTrace();
            return null;
        }
    }
}
